package src;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import src.Request;

/**
 * <p>Title: Environment.java</p>
 *
 * <p>Description: Helper class to save all the environment variables that are
 * needed to ensure proper configuration and execution of CGI scripts
 * </p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 *
 * @author Luping May and Tracie Hong
 * @version 1.0
 */
public class Environment {

    private HashMap<String, String> envMap;
    private ArrayList<String> restricted;
    private HashMap<String, ArrayList<String>> envMap2; //headers and params
  /**
   * Constructor for Environment object. Saves the information from the server
   * configuration file as well as from the request into a data structure so if
   * the request is for a cgi script, it can be executed properly.
   *
   * @param c HttpdConf file which contains some variables which need to be
   *   saved in order for cgi scripts to execute properly.
   * @param r Request object which contains request specific variables needed
   *   to execute cgi scripts
   * @param cl Socket used by the client to connect to the server
   */
  public Environment(HttpdConf c, Request r, Socket cl) {
    envMap = new HashMap<String, String>();
    envMap.put("SERVER_PROTOCOL", r.getVersion());
    envMap.put("SERVER_PORT", c.getListen());
    envMap.put("REQUEST_METHOD", r.getMethod());
    envMap.put("PATH_INFO", r.getId());
    envMap.put("PATH_TRANSLATED", c.solveAlias(r.getId()));
    envMap.put("QUERY_STRING", r.getQuery());
    envMap.put("SERVER_NAME", "localhost");
    envMap.put("RESTRICTED", r.getId());
    envMap.put("DOCUMENT_ROOT", c.getFromConf("DocumentRoot"));
    envMap2 = new HashMap<String, ArrayList<String>>();
    envMap2.put("HEADERS", r.getHeaders());
    envMap2.put("PARAMETERS", r.getParams());

    restricted = c.getRestricted();
  }//END Environment constructor

  /**
   * Function to save static variables into your data structure which can be
   * then used during script execution. Variables that can also be accessed
   * directly from the request object or the socket (objects passed in during
   * instantiation) can be saved here as well.
   * HINT: Most request variables that need to be saved need to have an HTTP_
   * variable name so take this into consideration when planning how to design
   * and save environment variables.
   */
  public void setEnv( String var ) {
    String str[] = var.split("\\s+");
    if( envMap.containsKey(str[0]) )
    {
        envMap.put(str[0], str[1]);
    }
    else
        System.out.println( "Could not set variable: " + str[0] + " -- Variable not found");
  }//END setEnv

  public String getEnv( String s )
  {
      return envMap.get(s);
  }//END getEnv

  /**
   * Function to return a data structure that contains all the environment
   * variables that were saved.
   *
   * @return ArrayList<String>. Chose as data type upon return due to parsing of variable
   *   content and name which both need to be stored.
   */
  public ArrayList<String> printEnv( ) {
    Set set = envMap.entrySet();
    Iterator it = set.iterator();
    ArrayList<String> envSet = new ArrayList<String>();
    while( it.hasNext() )
    {
        Entry e = (Entry) it.next();
        envSet.add( (String) e.getKey() + " " + (String) e.getValue() );
    }
    
    System.out.println(envSet);
    return envSet;
  }//END printEnv

  /**
   * Used to add another variable to the data structure. Usually used when the
   * data has not be stored yet through the setEnv function.
   *
   * @param var String that contains both the variable name and data. Used this
   *   way for parsing purposes later on.
   */
  public void addEnvVar(String var) {
    String [] str = var.split("\\s+");
    if( !envMap.containsKey( str[0]) )
    {
        envMap.put(str[0], str[1]);
    }
    else
        System.out.println("Could not add variable: " + str[0] + " -- Variable already exists");
  }//END addEnvVar

  public String getHeader( String str )
    {
      ArrayList tempHeaders = envMap2.get("HEADERS");
      for( int i = 0; i < tempHeaders.size(); i++ )
      {
          if( tempHeaders.get(i).toString().contains(str) )
          {
              System.out.println("Found: " + tempHeaders.get(i));
              return tempHeaders.get(i).toString();
          }
      }
      //String tempStr = tempHeaders.indexOf(str)
      return null;
  }//END getHeader

  public boolean isRestricted()
  {
      //System.out.print("This");
      //String [] splits = envMap.get("PATH_TRANSLATED").split("\\/");
      if( !envMap.get("PATH_INFO").equals("/"))
      {
      String splits[] = envMap.get("PATH_INFO").split("\\/");
      //System.out.println(splits[1]);
      System.out.println("Doc root + Path info " + envMap.get("DOCUMENT_ROOT") + "/" + splits[1]);
      System.out.println(restricted);
      return restricted.contains(envMap.get("DOCUMENT_ROOT") + "/" + splits[1]);
      }
      return restricted.contains(envMap.get("DOCUMENT_ROOT"));
  }//END isRestricted
}